﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using SimpleBoard.Backend.Server.Entities;
using SimpleBoard.Backend.Server.Extensions;
using SimpleBoard.Backend.Server.Models;
using SimpleBoard.Backend.Server.Services;
using System;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;

namespace SimpleBoard.Backend.Server.Controllers
{
    // TODO 鉴权和日志
    [Route("api/[controller]")]
    [ApiController]
    public class DeviceController : ControllerBase
    {
        public DeviceController(ApplicationDbContext dbContext, ILogger<DeviceController> logger, IDeviceService deviceService)
        {
            this.dbContext = dbContext;
            this.logger = logger;
            this.deviceService = deviceService;
        }

        private readonly ApplicationDbContext dbContext;
        private readonly IDeviceService deviceService;
        private readonly ILogger logger;

        /// <summary>
        /// 注册设备类型
        /// </summary>
        /// <param name="name">设备名称</param>
        /// <param name="descriptionJson">数据协议</param>
        /// <returns></returns>
        [HttpPost("[Action]")]
        public async Task<IActionResult> ResisterDevice([FromForm]string name, [FromForm]string descriptionJson)
        {
            var exsistsQuery = from deviceRestry in dbContext.DeviceRestries
                               where deviceRestry.Name == name
                               select deviceRestry.Name;
            if (exsistsQuery.Any())
            {
                return this.Fail("该设备类型已注册");
            }

            var valid = true;

            try
            {
                valid = JsonSerializer.Deserialize<DataFrameMeta>(descriptionJson)?.DataUnits.Any() ?? false;
            }
            catch
            {
                valid = false;
            }

            if (!valid)
            {
                return this.Fail("非法的数据协议格式");
            }

            dbContext.DeviceRestries.Add(new Entities.Users.DeviceRestry
            {
                Name = name,
                DataframeDescription = descriptionJson
            });

            await dbContext.SaveChangesAsync();

            return this.Success("注册成功");
        }

        /// <summary>
        /// 获取设备类型列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("[Action]")]
        public async Task<IActionResult> GetDeviceTypes()
        {
            var result = this.Success("获取成功", await dbContext.DeviceRestries.Select(x => new
            {
                x.Name,
                Protocol = this.deviceService.ParseDataProtocol(x.DataframeDescription),
                x.Id,
            }).ToArrayAsync());
            return result;
        }

        /// <summary>
        /// 添加设备，返回设备名称与Id
        /// </summary>
        /// <param name="name">设备名称</param>
        /// <param name="resistryId">设备种类Id</param>
        /// <returns></returns>
        [HttpPost("[Action]")]
        public async Task<IActionResult> AddDevice([FromForm]string name, [FromForm]int resistryId)
        {
            var exsistsQuery = from device in dbContext.Devices
                               where device.Name == name
                               select device.Name;
            if (exsistsQuery.Any())
            {
                return this.Fail("已存在同名设备");
            }

            var deviceTypeQuery = from deviceRestry in dbContext.DeviceRestries
                                  where deviceRestry.Id == resistryId
                                  select deviceRestry;
            if (!deviceTypeQuery.Any())
            {
                return this.Fail("指定的设备种类未注册");
            }

            var newDevice = dbContext.Devices.Add(new Entities.Users.Device
            {
                Name = name,
                DeviceType = deviceTypeQuery.Single(),
            }).Entity;

            await dbContext.SaveChangesAsync();

            return this.Success("添加成功", new { Name = name, Id = newDevice.DeviceId });
        }

        /// <summary>
        /// 删除指定设备
        /// </summary>
        /// <param name="deviceId">设备Id</param>
        /// <returns></returns>
        [HttpGet("[Action]")]
        public async Task<IActionResult> RemoveDevice(Guid deviceId)
        {
            var deviceQuery = dbContext.Devices.Where(x => x.DeviceId== deviceId);
            if (!deviceQuery.Any())
            {
                return this.Fail("指定Id的设备不存在");
            }
            dbContext.Devices.Remove(deviceQuery.Single());

            await dbContext.SaveChangesAsync();
            return this.Success("删除设备成功");
        }

        /// <summary>
        /// 获取设备列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("[Action]")]
        public async Task<IActionResult> GetDevices()
        {
            return this.Success("查询成功", await dbContext.Devices.Include(x => x.DeviceType).Select(x => new
            {
                x.Name,
                Type = x.DeviceType.Name,
                Id = x.DeviceId.ToString()
            }).ToArrayAsync());
        }
    }
}
